package wangwenjun.phase2.concurrencypattern.producerconsumer.waitnotify;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

/**
 * @author ChangLiang
 * @date 2020/6/10
 */
@Slf4j
public class EventQueue {

    static class Event{}

    private final int max;

    private final LinkedList<Event> eventQueue = new LinkedList<>();

    private final static int DEFAULT_MAX_EVENT = 10;

    public EventQueue()
    {
        this(DEFAULT_MAX_EVENT);
    }

    public EventQueue(int max)
    {
        this.max = max;
    }

    /**
     * post 方法会提交一个Event 至队尾，
     * 如果此时队列已经满了，那么提交的线程将会被阻塞
     * @param event
     */
    public void offer(Event event) {
        synchronized (eventQueue) {
            while (eventQueue.size() >= max) {
                log.warn(" the queue is full.");
                try {
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            log.info(" the new event is submitted, event:{}", event.toString());
            eventQueue.addLast(event);
            eventQueue.notifyAll();
        }
    }

    /**
     * take 方法会从队头获取数据，如果队列中没有可用数
     * 据，那么工作线程就会被阻塞
     * @return
     */
    public Event take(){
        synchronized (eventQueue) {
            while (eventQueue.isEmpty()) {
                log.warn(" the queue is empty.");
                try {
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Event event = eventQueue.removeFirst();
            eventQueue.notifyAll();
            log.info(" the event:{} is handled.", event);
            return event;
        }
    }

}
